package org.bookshare.validator.rule;

import java.io.IOException;
import java.util.List;

import org.benetech.beans.error.ValidationError.Severity;
import org.benetech.event.EventListener;
import org.bookshare.document.beans.HasOPF;
import org.bookshare.validator.error.MissingElementValidationError;
import org.bookshare.validator.error.MissingResourceValidationError;
import org.bookshare.validator.report.ValidationMetadata;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;

/**
 * Validate that resources (files) referred to in the OPF exist.
 *
 * @author Reuben Firmin
 */
public final class ResourcesExistRule implements Rule {

	/**
	 * Default constructor.
	 *
	 */
	public ResourcesExistRule() {
		// empty
	}

    /**
     * {@inheritDoc}
     */
    public void evaluate(final ValidationMetadata validationMetadata, final EventListener listener) {
    	final Document doc = ((HasOPF) validationMetadata.getDocumentSet()).getOPFDocument();
        listener.message("Checking " + doc.getBaseURI()
        		+ " to verify resource contents of the zip file (images, pdf, et fc)");
        final Element root = doc.getRootElement();

        final Element manifest = root.getChild("manifest", root.getNamespace());
        if (manifest == null) {
            validationMetadata.getDocumentViolations().put(doc, new MissingElementValidationError("manifest",
                            "root", doc.getBaseURI(), Severity.ERROR));
        } else {
        	final List<Element> items = (List<Element>) manifest.getChildren("item", root.getNamespace());
            for (Element item : items) {
            	final Attribute href = item.getAttribute("href");
            	try {
	                if (!validationMetadata.getDocumentSet().containsFile(href.getValue())) {
	                	if (validationMetadata.getDocumentSet().containsFileIgnoreCase(href.getValue())) {
	                		validationMetadata.getElementViolations().put(item, new MissingResourceValidationError(
	                                "OPF Manifest (but does contain file with case ignored)", href.getValue(), true));
	                	} else {
	                		validationMetadata.getElementViolations().put(item, new MissingResourceValidationError(
	                                    "OPF Manifest", href.getValue(), true));
	                	}
	                }
            	} catch (IOException e) {
            		// XXX
            	}
            }
        }
    }
}


